package com.geek.gkpush.framework.event.action;

import com.geek.gkpush.framework.event.EventMsgPersistFacade;
import com.geek.gkpush.framework.event.enums.PushStatusEnum;
import com.geek.gkpush.framework.event.model.EventMsgContext;
import com.geek.gkpush.framework.event.model.EventMsgRangeQueryModel;
import com.geek.gkpush.framework.event.model.EventMsgUpdateModel;
import com.geek.gkpush.util.str.StringCutUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * <h1>事件消息持久化更新处理类。</h1><br/>
 *
 * <h1><br/><a href="https://u.geekbang.org/subject/arch3/100614201">Java 业务架构实战营：https://u.geekbang.org/subject/arch3/100614201</a></h1><br/><h1><a href="https://gitee.com/ylimhhmily/BizArchPracticeCamp">Java 业务架构实战营代码地址：https://gitee.com/ylimhhmily/BizArchPracticeCamp</a></h1><br/><h1><a href="https://u.geekbang.org/subject/java4th/1001148?source=app_share">高级 Java 工程体系课 2023 版：https://u.geekbang.org/subject/java4th/1001148?source=app_share</a></h1><br/><h1><a href="https://time.geekbang.org/column/intro/100312101?tab=catalog">Dubbo 源码剖析与实战：https://time.geekbang.org/column/intro/100312101?tab=catalog</a></h1>
 *
 * @author hmilyylimh
 *         ^_^
 * @version 0.0.1
 *         ^_^
 * @date 2023/10/3
 *
 */
@Slf4j
@Component
public class EventMsgUpdateAction {

    @Autowired
    private EventMsgPersistFacade eventMsgPersistFacade;

    /**
     * <h2>将消息更新为 SUCC 成功结果。</h2>
     *
     * @param msgCtx
     * @param execResult
     * @return
     */
    public int update2Succ(EventMsgContext msgCtx, String execResult) {
        EventMsgUpdateModel updateModel  = new EventMsgUpdateModel();

        updateModel.setId(msgCtx.getId());
        updateModel.setBizId(msgCtx.getBizId());
        updateModel.setBizType(msgCtx.getBizType());

        updateModel.setPushStatus(PushStatusEnum.SUCC.getCode());
        updateModel.setSrcPushStatus(msgCtx.getPushStatus());
        if (StringUtils.isBlank(execResult)) {
            updateModel.setPushResult(PushStatusEnum.SUCC.getMsg());
        } else {
            updateModel.setPushResult(
                    StringCutUtils.cut(String.join("-", PushStatusEnum.SUCC.getMsg(), execResult), 1800));
        }

        // 修改为 SUCC 成功状态
        int effectCnt = eventMsgPersistFacade.updatePushStatusByCondition(updateModel);

        // 范围更新偏旧的事件消息，不需要框在事务里面，成功就成功，不成功的话那就等着后面继续补偿处理
        if (effectCnt > 0) {
            EventMsgRangeQueryModel rangeModel = EventMsgRangeQueryModel.create(msgCtx);
            eventMsgPersistFacade.rangeUpdateList2Succ(rangeModel);
        }
        return effectCnt;
    }

    /**
     * <h2>将事件消息更新为 FAIL 失败状态。</h2>
     *
     * @param: msgCtx
     * @param: execResult
     * @return: int
     */
    public int update2Fail(EventMsgContext msgCtx, String execResult) {
        EventMsgUpdateModel model = new EventMsgUpdateModel();

        model.setId(msgCtx.getId());
        model.setBizId(msgCtx.getBizId());
        model.setBizType(msgCtx.getBizType());

        model.setPushStatus(PushStatusEnum.FAIL.getCode());
        model.setSrcPushStatus(msgCtx.getPushStatus());
        model.setPushResult(StringCutUtils.cut(execResult, 1800));

        // 修改为 FAIL 成功状态
        return eventMsgPersistFacade.updatePushStatusByCondition(model);
    }
}